package hdoj;


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

//推箱子，注意只能推，如果到达边界就只能沿着边界移动了。如果到达墙角，就不能移动了
public class PushBox {

	private static final int OBSTACLE = 1;
	private static final int START = 4;	//搬运工的起始位置
	private static final int EXIT = 3;
	private static final int BOX = 2;	//箱子的初始位置
	
	
	public static final int[][] dir = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
	public static final int[][] against = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
	
	private static final int MAX = 9; 
	
	private int minStep = 0;
	
	private int rows, columns; 
	private int[][] maze = new int[MAX][MAX];
	
//	private boolean[][] visited = new boolean[MAX][MAX];
	private boolean[][][][] visited = new boolean[MAX][MAX][MAX][MAX];
	private boolean[][] peopleVisited = new boolean[MAX][MAX];
	
	public static void main(String[] args) {
		PushBox object = new PushBox();
		object.getRes();
	}
	
	public void getRes(){
		Scanner scanner = new Scanner(System.in);
		int testCase = scanner.nextInt();
		for(int t = 1; t <= testCase; t++){
			rows = scanner.nextInt();
			columns = scanner.nextInt();
			minStep = 0;
			int x = 0, y = 0;
			int personX = 0, personY = 0;
			for(int i = 0; i < rows; i++){
				for (int j = 0; j < columns; j++) {
					maze[i][j] = scanner.nextInt();
					if(maze[i][j] == START){
						personX = i;
						personY = j;
					}else if(maze[i][j] == BOX){
						x = i;
						y = j;
					}
				}
			}
			bfs(x, y, personX, personY);
			if(minStep == 0){
				System.out.println(-1);
			}else{
				System.out.println(minStep);
			}
		}
		scanner.close();
	}
	
	class Node{
		int x, y, step;
		int personX, personY;
		Node(int x, int y){
			this.x = x;
			this.y = y;
		}
	}
	
	
	public void bfs(int x, int y, int personX, int personY){
		Node node = new Node(x, y);
		node.personX = personX;
		node.personY = personY;
		Queue<Node> queue =  new LinkedList<>();
		queue.add(node);
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				for (int k = 0; k < rows; k++) {
					Arrays.fill(visited[i][j][k], false);
				}
			}
		}
		//visited[x][y] = true;
		visited[x][y][node.personX][node.personY] = true;
		while(!queue.isEmpty()){
			node = queue.poll();
			if(maze[node.x][node.y] == EXIT){
				minStep = node.step;
				return;
			}
			for(int i = 0; i < dir.length; i++){
				int curX = node.x + dir[i][0];
				int curY = node.y + dir[i][1];
				//如果遇到障碍
				if(curX < 0 || curX >= rows || curY < 0 || curY >= columns || maze[curX][curY] == OBSTACLE
						|| visited[curX][curY][node.personX][node.personY]){
					continue;
				}
				//如果不是障碍，我们还要判断对面是不是障碍
				int againstX = node.x + against[i][0];
				int againstY = node.y + against[i][1];
				//如果对面是障碍，我们同样不能到达该点
				if(againstX < 0 || againstX >= rows || againstY < 0 || againstY >= columns || 
						maze[againstX][againstY] == OBSTACLE){
					continue;
				}
				//此时人要站在对面，所以我们要判断人是否能走到该点
				//后来发现题目不是求的搬运工移动步数，而是最少需要推动箱子多少格
				
				//后来发现由于人的位置也是一个维度，所以我们不能单独的判断是否到过该点，而要加上人的位置
				int curStep = bfsPeople(node.personX, node.personY, againstX, againstY);
//				System.out.println("curX: " + node.personX + " curY: " + node.personY + " endX: " + againstX +
//						" endY: " + againstY + " curStep: " + curStep);
				if(curStep == -1){
					continue;
				}
				Node next = new Node(curX, curY);
				//next.step = node.step + curStep;
				next.step = node.step + 1;
				next.personX = againstX;
				next.personY = againstY;
				visited[curX][curY][node.personX][node.personY] = true;
				queue.add(next);
			}
		}
	}
	
	//计算推箱子的工人运动
	public int bfsPeople(int x, int y, int endX, int endY){
		Node node = new Node(x, y);
		int curStep = -1;
		Queue<Node> queue =  new LinkedList<>();
		queue.add(node);
		for(int i = 0; i < rows; i++){
			Arrays.fill(peopleVisited[i], false);
		}
		peopleVisited[x][y] = true;
		while(!queue.isEmpty()){
			node = queue.poll();
			if(node.x == endX && node.y == endY){
				curStep = node.step;
				return curStep;
			}
			for(int i = 0; i < dir.length; i++){
				int curX = node.x + dir[i][0];
				int curY = node.y + dir[i][1];
				//如果遇到障碍
				if(curX < 0 || curX >= rows || curY < 0 || curY >= columns || maze[curX][curY] == OBSTACLE
						|| peopleVisited[curX][curY]){
					continue;
				}
				Node next = new Node(curX, curY);
				next.step = node.step + 1;
				peopleVisited[curX][curY] = true;
				queue.add(next);
			}
		}
		return curStep;
	}
}
